﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "DrawArcByCenterEndPtElementBehavior.h"
#include "IUiView.h"
#include "IActionInputEventArgs.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

#define ACTION_INPUT_EDIT_OFFSET          L"EditOffsetId"

using namespace gcmp;

DrawArcByCenterEndPtElementBehavior::DrawArcByCenterEndPtElementBehavior(IDocument* pDoc)
    : m_pDoc(pDoc)
    , m_onInitActionCallback(nullptr)
    , m_defineInputDialogCallback(nullptr)
    , m_onActionInputEventCallback(nullptr)
    , m_onPropertyPanelEventCallback(nullptr)
    , m_onGetCenterPointCallback(nullptr)
    , m_onGetStartPointCallback(nullptr)
    , m_onGetEndPointCallback(nullptr)
    , m_onFinishCallback(nullptr)
    , m_onRadiusUpdatedCallback(nullptr)
    , m_onArcUpdatedCallback(nullptr)
    , m_onDestroyActionCallback(nullptr)
    , m_offset(0.0)
{
}

DrawArcByCenterEndPtElementBehavior::~DrawArcByCenterEndPtElementBehavior()
{
}

bool DrawArcByCenterEndPtElementBehavior::SetOnInitActionCallback(OnInitActionCallback callback)
{
    m_onInitActionCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetDefineInputDialogCallback(DefineInputDialogCallback callback)
{
    m_defineInputDialogCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnActionInputEventCallback(OnActionInputEventCallback callback)
{
    m_onActionInputEventCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnPropertyPanelEventCallback(OnPropertyPanelEventCallback callback)
{
    m_onPropertyPanelEventCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnGetCenterPointCallback(OnGetCenterPointCallback callback)
{
    m_onGetCenterPointCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnGetStartPointCallback(OnGetStartPointCallback callback)
{
    m_onGetStartPointCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnGetEndPointCallback(OnGetEndPointCallback callback)
{
    m_onGetEndPointCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnFinishCallback(OnFinishCallback callback)
{
    m_onFinishCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnRadiusUpdatedCallback(OnRadiusUpdatedCallback callback)
{
    m_onRadiusUpdatedCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnArcUpdatedCallback(OnArcUpdatedCallback callback)
{
    m_onArcUpdatedCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::SetOnDestroyActionCallback(OnDestroyActionCallback callback)
{
    m_onDestroyActionCallback = callback;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::DefinePromptMsg(std::wstring& promptMsg, const gcmp::DrawArcCenterEndStatus drs)
{
    switch (drs)
    {
    case DrawArcCenterEndStatus::DACES_GETTING_CENTER_POINT:
        promptMsg = GBMP_TR(L"单击确定圆弧圆心点");
        break;
    case DrawArcCenterEndStatus::DACES_GETTING_START_POINT:
        promptMsg = GBMP_TR(L"单击确定圆弧起点");
        break;
    case DrawArcCenterEndStatus::DACES_GETTING_END_POINT:
        promptMsg = GBMP_TR(L"单击确定圆弧终点");
        break;
    default:
        break;
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::DefineCursorType(gcmp::CursorType& cursorType, const gcmp::DrawArcCenterEndStatus drs)
{
    cursorType = CursorType::DrawArcCursor;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::DefineInputDialog(std::wstring& title, std::vector<gcmp::OwnerPtr<gcmp::IControlDefinition>>& inputItems)
{
    if (m_defineInputDialogCallback)
    {
        m_defineInputDialogCallback(title, inputItems);
        return true;
    }
    else
    {
        return false;
    }
}

bool DrawArcByCenterEndPtElementBehavior::GetOffsetValue(double& offset)
{
    offset = m_offset;
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::OnInitAction(IUiView* pCurrentView)
{
    if (m_onInitActionCallback)
    {
        m_onInitActionCallback(pCurrentView);
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::OnActionInputEvent(IActionInputEventArgs* pArgs)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pArgs, L"pArgs为空",L"GDMPLab",L"2024-03-30");
    const std::pair<std::wstring, gcmp::Any>& msg = pArgs->GetInputMessage();
    const std::wstring eventID = msg.first;
    gcmp::Any inputValue = msg.second;
    if (eventID == ACTION_INPUT_EDIT_OFFSET)
    {
        m_offset = inputValue.cast<double>();
    }
    else if (m_onActionInputEventCallback)
    {
        m_onActionInputEventCallback(pArgs);
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::OnPropertyPanelEvent(IPropertyPanelEventArgs* pArgs)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pArgs, L"pArgs为空",L"GDMPLab",L"2024-03-30");
    if (m_onPropertyPanelEventCallback)
    {
        m_onPropertyPanelEventCallback(pArgs);
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::OnEnterGettingCenterPointState(IUiView* pCurrentView)
{
    if (m_onGetCenterPointCallback)
    {
        m_onGetCenterPointCallback(pCurrentView);
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::OnEnterGettingStartPointState(IUiView* pCurrentView)
{
    if (m_onGetStartPointCallback)
    {
        m_onGetStartPointCallback(pCurrentView);
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::OnEnterGettingEndPointState(IUiView* pCurrentView)
{
    if (m_onGetEndPointCallback)
    {
        m_onGetEndPointCallback(pCurrentView);
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::OnDrawArcFinished(gcmp::IUiView* pCurrentView, const gcmp::Vector3d& centerPt, const gcmp::Vector3d& startPt,
                                const gcmp::Vector3d& endPt, const gcmp::ISnap* centerSnap, const gcmp::ISnap* startSnap, const gcmp::ISnap* endSnap)
{
    if (m_onFinishCallback)
    {
        m_onFinishCallback(pCurrentView, centerPt, startPt, endPt);
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::OnDestroyAction()
{
    if (m_onDestroyActionCallback)
    {
        m_onDestroyActionCallback();
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::GetGElementShapeOnRadiusUpdated(gcmp::IUiView* pCurrentView, const gcmp::Vector3d& centerPt,
        const gcmp::Vector3d& pos, const gcmp::ISnap* centerSnap, const gcmp::ISnap* posSnap, OwnerPtr<IGraphicsElementShape>& opGElementShape)
{
    if (m_onRadiusUpdatedCallback)
    {
        m_onRadiusUpdatedCallback(pCurrentView, centerPt, pos, opGElementShape);
    }
    return true;
}

bool DrawArcByCenterEndPtElementBehavior::GetGElementShapeOnArcUpdated(gcmp::IUiView* pCurrentView, const gcmp::Vector3d& centerPt,
        const gcmp::Vector3d& startPt, const gcmp::Vector3d& pos, const gcmp::ISnap* centerSnap, const gcmp::ISnap* startSnap,
        const gcmp::ISnap* posSnap, OwnerPtr<IGraphicsElementShape>& opGElementShape)
{
    if(m_onArcUpdatedCallback)
    {
        m_onArcUpdatedCallback(pCurrentView, centerPt, startPt, pos, opGElementShape);
    }
    return true;
}
